/**
 * 画板 created to by doujiabao
 */

import React, { Component } from 'react'

import Router from 'next/router'

import config from '~/static/config'
import moment from 'moment'

import Page from '@/components/Page'
import { HighlightOutlined } from '@ant-design/icons'
import {
    Button,
    Modal,
    Spin,
    message,
    Input,
} from 'antd'

const { confirm } = Modal

class DrawingBoard extends Component {

    state = {
        //加载状态
        loading: false,
        //颜色
        lineColor: '#000',
        //笔显示隐藏
        penVisible: false,
        //2d对象
        context2d: null,
        //按下标记
        onoff: false,
        //线宽
        linw: 4,
        //点击时的坐标
        old: {
            x: 0,
            y: 0
        },
        //生成图片的过程
        generateLoading: false,
        //图片元素
        imgEvSrc: '',
        //
        visible: false,
        //上传状态
        uploading: false,
        //作品名称
        fileName: '',
    }

    canvas = React.createRef()

    pen = React.createRef()

    img = React.createRef()

    componentDidMount() {
        this.setState({
            context2d: this.canvas.current.getContext('2d')
        }, () => {
            const that = this

            //默认背景颜色
            this.state.context2d.fillStyle = "#ffffff";
            this.state.context2d.fillRect(0, 0, 1160, 600);

            that.canvas.current.addEventListener('mousedown', function (e) {
                if (that.isInCanvas(e)) {
                    that.setState({
                        onoff: true,
                    }, () => {
                        document.body.style.cursor = 'none'

                        //这里是为了校对鼠标在canvas和窗口中的坐标差
                        const x = e.pageX - that.canvas.current.getBoundingClientRect().left
                        const y = e.pageY - that.canvas.current.getBoundingClientRect().top

                        that.setState({
                            penVisible: true,
                            old: {
                                x,
                                y
                            }
                        })
                    })
                }
            }, false)

            document.addEventListener('mouseup', function (e) {
                that.setState({
                    onoff: false
                }, () => {
                    document.body.style.cursor = 'default'

                    that.setState({
                        penVisible: false,
                    })
                })
            })

            document.addEventListener('mousemove', function (e) {
                if (that.isInCanvas(e)) {
                    //x
                    that.pen.current.style.left = e.pageX - that.canvas.current.getBoundingClientRect().left + 12 + 'px'
                    //y
                    that.pen.current.style.top = e.pageY - that.canvas.current.getBoundingClientRect().top + 38 + 'px'
                    //画
                    const {
                        context2d,
                        onoff,
                        lineColor,
                        linw,
                        old,
                    } = that.state

                    if (context2d && onoff) {
                        //同按下时...
                        const newX = e.pageX - that.canvas.current.getBoundingClientRect().left
                        const newY = e.pageY - that.canvas.current.getBoundingClientRect().top

                        context2d.beginPath()               //丢弃任何当前定义的路径并且开始一条新的路径。它把当前的点设置为 (0,0)。       
                        context2d.moveTo(old.x, old.y)      //移动到点击时候的坐标，以那个坐标为原点      
                        context2d.lineTo(newX, newY)        //绘制新的路径       
                        context2d.strokeStyle = lineColor
                        context2d.lineWidth = linw
                        context2d.lineCap = "round"
                        context2d.stroke()

                        that.setState({
                            old: {
                                x: newX,
                                y: newY
                            }
                        })
                    }
                } else {
                    document.body.style.cursor = 'default'

                    that.setState({
                        penVisible: false,
                        onoff: false
                    })
                }
            }, true)
        })
    }

    /**
     * 鼠标是否在画板内部
     */
    isInCanvas = (e) => {
        if (!!e && this.canvas.current) {

            let evX = e.pageX
            let evY = e.pageY

            // evX > canvas left border && evX < canvas right border && evY > canvas top border && evY < canvas bottom border

            let canvasLeft = this.canvas.current.getBoundingClientRect().left
            let canvasRight = canvasLeft + this.canvas.current.getBoundingClientRect().width
            let canvasTop = this.canvas.current.getBoundingClientRect().top
            let canvasBottom = canvasTop + this.canvas.current.getBoundingClientRect().height

            if (evX > canvasLeft && evX < canvasRight && evY > canvasTop && evY < canvasBottom) {
                return true
            } else {
                return false
            }

        } else {
            return false
        }
    }

    //切换颜色
    handleColorChange = (e) => {
        this.setState({ lineColor: e.target.value })
    }

    /**
     * 发布
     */
    handleRelease = () => {
        const that = this

        confirm({
            cancelText: '不发了',
            okText: '取好名字了',
            title: '给作品取个名字吧?',
            content: <Input
                placeholder='起个特殊的名字吧，空白会被覆盖。'
                onChange={(e) => {
                    this.setState({
                        fileName: e.target.value
                    })
                }}
            />,
            onOk() {
                that.setState({
                    generateLoading: true
                }, () => {
                    that.setState({
                        imgEvSrc: that.canvas.current.toDataURL("image/png")
                    }, () => {
                        that.setState({
                            generateLoading: false,
                            visible: true
                        })
                    })
                })
            }
        })
    }

    //*废弃
    //将base64转换成可用formdata提交的文件,urlData base64的url,type 0图片 1视频
    convertBase64UrlToBlob = (urlData) => {
        //去掉url的头，并转换为byte            
        var bytes = window.atob(urlData.split(',')[1])
        //处理异常,将ascii码小于0的转换为大于0  
        var ab = new ArrayBuffer(bytes.length);
        var ia = new Uint8Array(ab);
        for (var i = 0; i < bytes.length; i++) {
            ia[i] = bytes.charCodeAt(i);
        }

        return new Blob([ab], {
            type: 'image/png'
        })
    }

    dataURLtoFile(dataurl, filename = 'file') {
        let arr = dataurl.split(',')
        let mime = arr[0].match(/:(.*?);/)[1]
        let suffix = mime.split('/')[1]
        let bstr = atob(arr[1])
        let n = bstr.length
        let u8arr = new Uint8Array(n)
        while (n--) {
            u8arr[n] = bstr.charCodeAt(n)
        }
        return new File([u8arr], `${filename}.${suffix}`, { type: mime })
    }

    handleCancel = () => {
        this.setState({
            visible: false
        })
    }

    handleOk = () => {
        this.setState({
            uploading: true
        }, () => {
            let file = this.dataURLtoFile(this.state.imgEvSrc, this.state.fileName)

            var body = new FormData()

            body.append('name', this.state.fileName)
            body.append('file', file)
            body.append('time', Math.round(moment().valueOf() / 1000))

            fetch(`${config.baseURL}/blog/uploadImageDrawing`, {
                method: "POST",
                body
            })
                .then(response => {
                    return response.json()
                })
                .then(res => {
                    this.setState({
                        uploading: false,
                        visible: false
                    }, () => {
                        //jump to drawing list
                        Router.push('/drawingList')
                        //tip
                        message.success('发布成功，快去看看吧')
                    })
                })
                .catch(err => {
                    this.setState({
                        uploading: false
                    })
                })
        })
    }

    render() {

        const {
            loading,
            lineColor,
            penVisible,
            generateLoading,
            imgEvSrc,
            visible,
            uploading,
        } = this.state

        return (<Page
            loading={loading}
        >
            <div className='main'>

                <Spin spinning={generateLoading}>

                    <div className='utils'>
                        <input type="color" name="color" id="color" onChange={this.handleColorChange} />
                        <Button type="primary" onClick={this.handleRelease}>发布</Button>
                    </div>

                    <i ref={this.pen} className='pen' style={{ color: lineColor, display: penVisible ? 'block' : 'none' }}><HighlightOutlined /></i>

                    <canvas
                        id="canvas"
                        width="1160"
                        height="600"
                        ref={this.canvas}
                    ></canvas>

                </Spin>

            </div>

            <Modal
                title='发布画布'
                visible={visible}
                maskClosable={false}
                cancelText='取消'
                okText='发布'
                width={800}
                onCancel={this.handleCancel}
                onOk={this.handleOk}
                confirmLoading={uploading}
            >
                <div className='output'>
                    <img ref={this.img} src={imgEvSrc} alt="myworks" />
                </div>
            </Modal>

            <style jsx>{`
                .main {
                    max-width: 1200px;
                    min-height: calc(100vh - 100px);
                    color: #000000;
                    margin: 0 auto;
                    padding-top: 100px;
                }
                .utils {
                    font-size: 24px;
                    box-sizing: border-box;
                    padding: 10px;
                    display: flex;
                    align-items: center;
                    margin-bottom: 10px;
                    justify-content: space-between;
                }
                .pen {
                    width: 30px;
                    height: 30px;
                    text-align: center;
                    line-height 30px;
                    font-size: 24px;
                    position: absolute;
                    right: 0;
                    top: 0;
                    z-index: 99;
                    -moz-user-select: none;
                    -webkit-user-select: none;
                    -ms-user-select: none;
                    -khtml-user-select: none;
                    user-select: none;
                }
                #canvas {
                    display: block;
                    margin: 0 auto;
                    border-radius: 4px;
                    background: #ffffff;
                    box-shadow: 8px 14px 38px rgba(39,44,49,.06), 1px 3px 8px rgba(39,44,49,.03);
                }
                .output {
                    width: 100%;
                }
                .output img {
                    display: block;
                    width: 100%;
                }
            `}</style>
        </Page>)
    }
}

export default DrawingBoard